<?php
//程序开始时间 
$start_time =  microtime(true);
set_time_limit(0);
define('u_index', '_lblindex_');
//eyou.txt,  autoload.txt, pcX.txt, autoload_old.txt
//使用cookie记录时间
$filename = $argv[1];
//存储临时解密文件的目录
$savedir = './temp/';
//每次执行数量 
$stepnum = 100;
$data = file_get_contents($filename);
$data = trim($data, '?>');
//执行正则匹配 goto xxxx;
$goto_preg = '/(?<=goto)[\s]+([^;\s]+)[\s]*(?=;)/isU';
//处理注释部分
$preg_s = '/\/\*[\s\S]+(?=\*\/)\*\//isU';
//if
$preg_if = '/if\(([^;]+)\)\s*goto\s+(\w+);/isU';
//中止部分
$stop_preg = '/[\s\S]*(return|exit|die|goto)[^;]*;/isU';  //return|exit|  
preg_match_all($goto_preg, $data, $matches);
//最后一个key
$end_key = count($matches[1]) - 1;
$match_ifarr = array();
//echo $end_key; exit();
if (!file_exists($savedir . $filename . '_prev.txt')) {
	if (preg_match($preg_s, $data, $match_s)) {
		$data =  preg_replace($preg_s, '', $data);
	}
	foreach ($matches[1] as $key => $value) {
		$data =  preg_replace('/' . $value . ';/', u_index . $key . ';', $data);
		$data =  preg_replace('/' . $value . ':/', u_index . $key . ':', $data);
	}
	if (preg_match_all($preg_if, $data, $match_if)) {
		foreach ($match_if[0] as $key => $val) {
			$match_ifarr[$match_if[2][$key]]['value'] = $match_if[2][$key];
			$match_ifarr[$match_if[2][$key]]['all_if'] = $match_if[0][$key];
			$match_ifarr[$match_if[2][$key]]['key'] = $key;
		}
		file_put_contents($savedir . $filename . '_matches_if.txt', '<?php return ' . var_export($match_ifarr, 1) . '; ?>');
	}
	file_put_contents($savedir . $filename . '_prev.txt', $data);
	echo ('生成预处理文件' . $savedir . $filename . '_prev.txt;');
}

// 预处理结束 
$data = file_get_contents($savedir . $filename . '_prev.txt');
if (file_exists('./' . $savedir . $filename . '_matches_if.txt')) {
	$match_ifarr = require $savedir . $filename . '_matches_if.txt';
} else {
	$match_ifarr = array();
}

// var_dump($match_ifarr); exit;
// $goto_arr = preg_split("/goto[\s]+/", $data, 2, PREG_SPLIT_NO_EMPTY);
$value_index = u_index . '0';
foreach ($matches[1] as $key => $value) {
	if (empty($data)) {
		exit('数据获取失败！');
	}
	// 解密
	$data_jiemi = jiemi($data, $value_index, $key);
	$data = $data_jiemi['data'];
	$value_index = $data_jiemi['index'];
	if (empty($value_index)) {
		$data = prety($data);
		file_put_contents($savedir . $filename . '_de.php', $data);
		echo 'goto解密完毕！查看解密文件' . $savedir . $filename . '_de.php' . '。用时:' . round((microtime(true) - $start_time), 4) . '秒';
		exit;
	}
	//如果没有了goto  直接下一步
	//
}

//var_dump($key);
//var_dump($data);
//必要的格式化下
//替换to
// $data = prety($data);
// file_put_contents($savedir . $filename . '_de.txt', $data);
// echo 'goto解密完毕！查看解密文件' . $savedir . $filename . '_de.txt' . '。用时:' . round((microtime(true) - $start_time), 4) . '秒';

function jiemi($data, $value, $key)
{
	global $savedir;
	global $end_key;
	global $goto_preg;
	global $savedir;
	global $filename;
	global $preg_if;
	global $stop_preg;
	global $match_ifarr;
	$pos_start =  strpos($data, $value . ";");
	$pos_end =    strpos($data, $value . ":");
	//echo $value;
	//如果存在判断
	if (isset($match_ifarr[$value]['value'])) {
		// var_dump($data);
		// print_r($match_ifarr[$value]);
		$data = jiemi_if($data, $match_ifarr[$value]['all_if'], $match_ifarr[$value]['value'], $key);
		// var_dump($data);
		//echo '遇到判断<br/>'; exit;
	} else {
		if ($pos_end > 0 && $pos_end > $pos_start) {
			//得到前面的字符
			$str_prev_arr = preg_split("/goto[\s]+" . $value . ";/isU", $data, 2, PREG_SPLIT_NO_EMPTY);
			$str_prev = isset($str_prev_arr[0]) ? $str_prev_arr[0] : ' ';
			//后面的
			$str_after_arr = preg_split("/" . $value . ":/isU", $data, 2, PREG_SPLIT_NO_EMPTY);
			//这里如何中止成了关键  不能接上全部  遇到 return 和 exit  goto  要停止 
			$str_after = isset($str_after_arr[1]) ? $str_after_arr[1] : ' ';

			$str_temp = get_end($value, $str_after, $key);
			//file_put_contents($savedir.$filename.'_'.$value.'.txt',$str_temp);
			isset($str_prev_arr[1]) ? $str_prev_arr[1] : $str_prev_arr[1] = '';
			$str_center = substr($str_prev_arr[1], 0, strpos($str_prev_arr[1], $value . ':'));
			$str_end = substr($str_after, strpos($str_after, $str_temp) + strlen($str_temp));
			$data = $str_prev . $str_temp . $str_center . $str_end;
			//去掉一些没用的
			//$data =  preg_replace('/goto\s+'.$value.';/isU','',$data); 
			//$data =  preg_replace('/'.$value.':/isU','',$data);    
		} else {
			// exit($key.'没找到'.$value."可能存在位置异常<br/>");
			$data =  preg_replace('/goto\s+' . $value . ';/isU', '', $data);
			$data =  preg_replace('/' . $value . ':/isU', '', $data);
		}
	}

	$goto_arr = preg_split("/goto[\s]+/", $data, 2, PREG_SPLIT_NO_EMPTY);
	if (isset($goto_arr[1])) {
		$value_index = substr($goto_arr[1], 0, strpos($goto_arr[1], ';'));
	} else {
		$value_index = '';
	}
	// file_put_contents($savedir.$filename.'_index_'.$value.'.txt', $value.'=>'.$value_index); 
	return array('data' => $data, 'index' => $value_index);
}

function prety($data)
{
	$data = str_replace("} ", "} " . PHP_EOL, $data);
	$data =  str_replace("; ", "; " . PHP_EOL, $data);
	$data = str_replace(" { ", " { " . PHP_EOL, $data);
	return $data;
}


//解密if 存在 true  false 两种情况 都记录下
/*
  $data 整个 data
  
 */
function jiemi_if($data, $all_if, $value, $key)
{
	global $savedir;
	global $goto_preg;
	// 如何破解if的思路：  同时解密 1 和 0的两种情况  根据解密后的对比来选择 
	// 假如是true 解密1  则去掉 if 
	$data_1 = str_replace($all_if, 'goto ' . $value . ';', $data);
	// 获取前面
	$str_prev_arr = preg_split("/goto[\s]+" . $value . ";/isU", $data_1, 2, PREG_SPLIT_NO_EMPTY);
	$str_prev = $str_prev_arr[0];
	//后面的
	$str_after_arr = preg_split("/" . $value . ":/", $data_1, 2, PREG_SPLIT_NO_EMPTY);
	$str_after = isset($str_after_arr[1]) ? $str_after_arr[1] : $str_after_arr[1] = '';
	isset($str_prev_arr[1]) ? $str_prev_arr[1] : $str_prev_arr[1] = '';
	$str_center = substr($str_prev_arr[1], 0, strpos($str_prev_arr[1], $value . ":"));
	$str_temp = get_end($value, $str_after, $key);
	$str_end = substr($str_after, strpos($str_after, $str_temp) + strlen($str_temp));
	$data_1 = $str_prev . $str_temp . $str_center . $str_end;
	$data_1 = preg_replace('/goto\s+' . $value . ';/', '', $data_1);
	$data_1 = str_replace($value . ':', '', $data_1);
	//假如是false 解密0  如果是false 第一项
	$data_0 = str_replace($all_if, '', $data);
	$data_0 = preg_replace('/goto\s+' . $value . ';/', '', $data_0);
	$data_0 = str_replace($value . ':', '', $data_0);
	// var_dump($data_0);
	// var_dump($data_1);
	// exit;
	// file_put_contents($savedir.$value.'-1.txt',$data_1);
	// file_put_contents($savedir.$value.'-0.txt',$data_0); 
	// 解密后自动判断下到底选1 还是选0
	preg_match($goto_preg, $data_0, $match_goto);
	$data_part = preg_split("/goto[\s]+" . $match_goto[1] . ";/isU", $data_0, 2, PREG_SPLIT_NO_EMPTY);
	// 正常的话 value  和value2不可能还在合并后的里面 否则就是错的 
	if (strpos($data_part[0], '_lblindex_') !== false) {
		echo $all_if . '选了true <br/>';
		return $data_1;
	} else {
		echo $all_if . '选了false<br/>';
		return $data_0;
	}
}

// 分解 截止点 
function  get_end($value, $str_after, $key)
{
	global $savedir;
	global $stop_preg;
	global $match_ifarr;
	$str_temp  = '';
	if (preg_match_all($stop_preg, $str_after, $stop_arr_all)) {
		isset($stop_arr_all[0][1]) ? $stop_arr_all[0][1] : $stop_arr_all[0][1] = '';
		//如果存在{  那就要把下一个截止点} 带回 也带回 
		if (strpos($stop_arr_all[0][0], '{') !== false || strpos($stop_arr_all[0][0], 'if') !== false) {
			$str_temp = $stop_arr_all[0][0] . $stop_arr_all[0][1];
			// $str_temp = $str_after;
		} else {
			$str_temp = $stop_arr_all[0][0];
		}
	} else {
		$str_temp = $str_after;
	}
	// file_put_contents($savedir.$key.'_end_'.$value.'.txt',$str_temp); 
	return $str_temp;
}
